<template>
  <div ref="containerTableRef" class="common-table-wrap" style="background: #ffffff">
    <div v-if="isShowMenu" class="menu">
      <el-button
        v-if="menuConfig.isShowFull"
        text
        :title="isExpandAllTree ? '折叠树表格' : '展开树表格'"
        type="primary"
        @click="handleExpandTree"
      >
        <el-icon>
          <Fold v-if="isExpandAllTree" />
          <Expand v-else />
        </el-icon>
      </el-button>

      <el-button v-if="menuConfig.isShowFull" text type="primary" @click="clickFullScreen">
        <vab-icon :icon="isFullscreen ? 'fullscreen-exit-fill' : 'fullscreen-fill'" />
      </el-button>
      <el-popover v-if="menuConfig.isShowSize" popper-class="custom-table-radio" trigger="hover">
        <el-radio-group v-model="lineHeight">
          <el-radio label="medium">大</el-radio>
          <el-radio label="small">中</el-radio>
          <el-radio label="mini">小</el-radio>
        </el-radio-group>
        <template #reference>
          <el-button text type="primary">
            <vab-icon icon="line-height" />
          </el-button>
        </template>
      </el-popover>
    </div>
    <div class="common-vxe-table">
      <vxe-table
        ref="tableV2Ref"
        v-loading="isLoading"
        align="center"
        :auto-resize="true"
        :border="border ?? true"
        :cell-class-name="dynamicCellClassName"
        :checkbox-config="{
          checkMethod: checkMethod,
          showHeader: true,
          checkStrictly: treeCheckStrictly
        }"
        :column-config="{
          minWidth: minWidth || 120,
          resizable: columnResizable || true
        }"
        :data="elTableData.datalist"
        :edit-config="editConfig"
        :footer-cell-class-name="getFooterCellClassName"
        :footer-method="getSummery"
        :keep-source="isClickEdit"
        :max-height="height"
        :radio-config="{
          checkMethod: checkMethod,
          checkStrictly: treeCheckStrictly
        }"
        :row-config="{
          useKey: true,
          height: rowHeight,
          keyField: isTree ? 'id' : '',
          isCurrent: isSelectRow || isHighLightRow
        }"
        :show-footer="showSummary"
        :show-header-overflow="true"
        :size="lineHeight"
        :stripe="stripe ?? true"
        :tree-config="
          isTree
            ? {
                rowField: treeRowField,
                parentField: treeparentField,
                transform: true,
                expandRowKeys: expandRowKeys
              }
            : {}
        "
        @cell-click="handleCellClick"
        @cell-dblclick="handleCellDBClick"
        @checkbox-all="handleSelectionChange"
        @checkbox-change="handleSelectionChange"
        @radio-change="handleRadioChange"
        @sort-change="handleSorted"
      >
        <template v-for="item in columnList" :key="item.value">
          <template v-if="!item.isShowCallBack || item.isShowCallBack()">
            <vxe-column
              v-if="item.type === TableColumnOrFormTypeEnum.SELECTION"
              :align="item.align || 'center'"
              :fixed="item.fixed"
              :header-align="item.headerAlign || 'center'"
              :min-width="item.minWidth"
              type="checkbox"
              :width="item.width || '60px'"
            />
            <vxe-column
              v-if="item.type === TableColumnOrFormTypeEnum.SELECTRADIO"
              :align="item.align || 'center'"
              :fixed="item.fixed"
              :header-align="item.headerAlign || 'center'"
              :min-width="item.minWidth"
              type="radio"
              :width="item.width || '60px'"
            />
            <vxe-column
              v-if="item.type === TableColumnOrFormTypeEnum.INDEX"
              :align="item.align || 'center'"
              :fixed="item.fixed"
              :header-align="item.headerAlign || 'center'"
              :min-width="item.minWidth"
              title="序号"
              :tree-node="isTree"
              type="seq"
              :width="item.width || '60px'"
            />
            <vxe-column
              v-if="item.type === TableColumnOrFormTypeEnum.EXPAND"
              :fixed="item.fixed"
              type="expand"
              :width="item.width || '60px'"
            >
              <template #content="{ row, rowIndex }">
                <slot name="expandContent" v-bind="{ row, rowIndex }"></slot>
              </template>
            </vxe-column>

            <vxe-column
              v-if="item.type === TableColumnOrFormTypeEnum.DYNAMIC"
              :align="item.align || 'center'"
              :fixed="item.fixed"
              :header-align="item.headerAlign || 'center'"
              :min-width="item.minWidth"
              title="行操作"
              width="135px"
            >
              <template #default="{ row, rowIndex }">
                <el-button :icon="Plus" link type="primary" @click="onAddRow(rowIndex)" />
                <el-button
                  :disabled="elTableData.datalist.length <= 1 && isMustHaveOneRow"
                  :icon="Delete"
                  link
                  type="primary"
                  @click="onDelRow(row, rowIndex)"
                />
              </template>
            </vxe-column>
            <template v-if="isClickEdit">
              <vxe-column
                v-if="formItemTypes.includes(item.type)"
                :align="item.align || 'center'"
                :edit-render="{ autofocus: '.vxe-input--inner' }"
                :field="item.value"
                :fixed="item.fixed"
                :header-align="item.headerAlign || 'center'"
                :min-width="item.minWidth"
                :sortable="!!item.sortable"
                :title="item.label"
                :width="item.width + 'px'"
              >
                <template #default="{ row }">
                  <template v-if="item.type === TableColumnOrFormTypeEnum.SELECT">
                    <template v-if="row && row.senum && row.senum[item.value]">
                      <span :style="{ color: row.senum[item.value].color }">
                        {{ row.senum[item.value].dictLabel }}
                      </span>
                    </template>
                    <template v-else>
                      {{ getTextKeyValue(row, item.value) }}
                    </template>
                  </template>
                  <template v-if="item.type === TableColumnOrFormTypeEnum.SELECTTREE">
                    <template v-if="item.valueShow">
                      {{ getTextKeyValue(row, item.valueShow) }}
                    </template>
                    <template v-else>
                      {{ getTextKeyValue(row, item.value) }}
                    </template>
                  </template>
                  <template v-if="item.type === TableColumnOrFormTypeEnum.MONEYINPUT">
                    <span style="display: block; text-align: right">
                      {{ getMoneyValue(row, item.value) }}
                    </span>
                  </template>
                  <template v-else>
                    {{ getTextKeyValue(row, item.value) }}
                  </template>
                </template>
                <template #edit="scope">
                  <CommonColumnItem
                    v-model="scope.row"
                    :dynamic-config="dynamicConfig"
                    :item="item"
                    :option-list="getOptionLists(item.dictCode, item.dictUrl, item.value)"
                    :prop-name="tableData.propName"
                    :row-index="scope.rowIndex"
                    :rules="tableData.rules || []"
                    @on-handle-change-value="onHandleChange"
                    @on-handle-confirm-selection="onHandleConfirmSelection"
                    @on-open-dynamic-table-select="onOpenDynamicTableSelect"
                  />
                </template>
              </vxe-column>
              <vxe-column
                v-if="item.type === TableColumnOrFormTypeEnum.SLOT"
                :align="item.align || 'center'"
                :edit-render="{}"
                :field="item.value"
                :fixed="item.fixed"
                :header-align="item.headerAlign || 'center'"
                :min-width="item.minWidth"
                :show-overflow="item.overflow"
                :sortable="!!item.sortable"
                :title="item.label"
                :width="item.width"
              >
                <template #default="{ row }">
                  <template v-if="item.valueShow">
                    {{ getTextKeyValue(row, item.valueShow) }}
                  </template>
                  <template v-else>
                    {{ getTextKeyValue(row, item.value) }}
                  </template>
                </template>
                <template #edit="{ row, rowIndex }">
                  <slot :name="item.slotName" :row="row" :row-index="rowIndex"></slot>
                </template>
              </vxe-column>
            </template>
            <template v-else>
              <vxe-column
                v-if="formItemTypes.includes(item.type)"
                :align="item.align || 'center'"
                :edit-render="{ autofocus: '.vxe-input--inner' }"
                :field="item.value"
                :fixed="item.fixed"
                :header-align="item.headerAlign || 'center'"
                :min-width="item.minWidth"
                :sortable="!!item.sortable"
                :title="item.label"
                :width="item.width + 'px'"
              >
                <template #default="scope">
                  <CommonColumnItem
                    v-model="scope.row"
                    :dynamic-config="dynamicConfig"
                    :item="item"
                    :option-list="getOptionLists(item.dictCode, item.dictUrl, item.value)"
                    :prop-name="tableData.propName"
                    :row-index="scope.rowIndex"
                    :rules="tableData.rules || []"
                    @on-handle-change-value="onHandleChange"
                    @on-handle-confirm-selection="onHandleConfirmSelection"
                    @on-open-dynamic-table-select="onOpenDynamicTableSelect"
                  />
                </template>
              </vxe-column>
              <vxe-column
                v-if="item.type === TableColumnOrFormTypeEnum.SLOT"
                :align="item.align || 'center'"
                :field="item.value"
                :fixed="item.fixed"
                :header-align="item.headerAlign || 'center'"
                :min-width="item.minWidth"
                :show-overflow="item.overflow"
                :sortable="!!item.sortable"
                :title="item.label"
                :width="item.width"
              >
                <template #default="{ row, rowIndex }">
                  <slot :name="item.slotName" :row="row" :row-index="rowIndex"></slot>
                </template>
              </vxe-column>
            </template>
            <vxe-column
              v-if="item.type === TableColumnOrFormTypeEnum.ENUM"
              :align="item.align || 'center'"
              :field="item.value"
              :fixed="item.fixed"
              :header-align="item.headerAlign || 'center'"
              :min-width="item.minWidth"
              :show-overflow="item.overflow"
              :sortable="!!item.sortable"
              :title="item.label"
              :width="item.width"
            >
              <template #default="{ row }">
                <template v-if="row && row.senum && row.senum[item.value]">
                  <span :style="{ color: row.senum[item.value].color }">
                    {{ row.senum[item.value].dictLabel }}
                  </span>
                </template>
                <template v-else>{{ row[item.value] }}</template>
              </template>
            </vxe-column>
            <vxe-column
              v-if="item.type === TableColumnOrFormTypeEnum.ENUMTEXT"
              :align="item.align || 'center'"
              :field="item.value"
              :fixed="item.fixed"
              :header-align="item.headerAlign || 'center'"
              :min-width="item.minWidth"
              :show-overflow="item.overflow"
              :sortable="!!item.sortable"
              :title="item.label"
              :width="item.width"
            >
              <template #default="{ row }">
                {{ getEnumText(row, item.dictCode, item.value) }}
              </template>
            </vxe-column>
            <vxe-column
              v-if="item.type === TableColumnOrFormTypeEnum.OBJECT"
              :align="item.align || 'center'"
              :field="item.value"
              :fixed="item.fixed"
              :header-align="item.headerAlign || 'center'"
              :min-width="item.minWidth"
              :show-overflow="item.overflow"
              :sortable="!!item.sortable"
              :title="item.label"
              :width="item.width"
            >
              <template #default="{ row }">
                {{ getObjectKeyvalue(row, item.value) }}
              </template>
            </vxe-column>
            <vxe-column
              v-if="item.type === TableColumnOrFormTypeEnum.MONEYTEXT"
              :align="item.align || 'right'"
              :field="item.value"
              :fixed="item.fixed"
              :header-align="item.headerAlign || 'center'"
              :min-width="item.minWidth"
              :show-overflow="item.overflow"
              :sortable="!!item.sortable"
              :title="item.label"
              :width="item.width"
            >
              <template #default="{ row }">
                {{ getMoneyValue(row, item.value) }}
              </template>
            </vxe-column>

            <vxe-column
              v-if="item.type === TableColumnOrFormTypeEnum.TEXT || !item.type"
              :align="item.align || 'center'"
              :field="item.value"
              :fixed="item.fixed"
              :header-align="item.headerAlign || 'center'"
              :min-width="item.minWidth"
              :show-overflow="item.overflow"
              :sortable="!!item.sortable"
              :title="item.label"
              :width="item.width"
            />
          </template>
        </template>

        <slot :emit-edit-id="emitEditId" :is-edit-by-row="tableV2Ref?.isEditByRow" name="opreration"></slot>
        <template #empty>
          <span v-if="isShowEmptyText && !isDynamic">
            {{ emptyText || "暂无数据" }}
          </span>
          <div v-else-if="isDynamic && elTableData.datalist.length <= 1" class="empty-btn">
            <el-button type="primary" @click="onAddRow(0)">新增</el-button>
          </div>
          <el-image v-else class="vab-data-empty" :src="getDataEmptyImg()" />
        </template>
      </vxe-table>
    </div>
    <div class="pager">
      <vxe-pager
        v-if="isShowPagination"
        v-model:current-page="tableQueryForm.pageNum"
        v-model:page-size="tableQueryForm.pageSize"
        align="center"
        background
        :layouts="defaultLayout"
        :page-sizes="pageSizes"
        :total="tableData.total"
        @page-change="handlePageChange"
      />
    </div>
  </div>
</template>

<script>
import Sortable from "sortablejs";
import { TableColumnOrFormTypeEnum } from "@/plugins/commonType.enum.ts";
import CommonColumnItem from "./CommonColumnItem.vue";
import { Delete, Plus } from "@element-plus/icons-vue";
import { doSorted, backTableHeight, getLocalStorage, queryList, getDataEmptyImg } from "@/api/mains";
import { hODeepClone } from "@/utils/index";
import { formatMoneyThoud } from "@/utils/money";
import { uuid } from "@/utils";
import { useRoute } from "vue-router";
import { useFullscreen } from "@vueuse/core";
import mitt from "mitt";
import _ from "lodash";
import { confirm } from "@/utils/MessageUtils";

export default defineComponent({
  name: "CommonTableV2",
  components: {
    CommonColumnItem
  },
  props: {
    queryForm: {
      type: Object,
      default: () => {
        return {};
      }
    },
    delRows: {
      type: Array,
      default: () => []
    },
    delRowIds: {
      type: Array,
      default: () => []
    },
    selectionValues: {
      type: Array,
      default: () => []
    },
    modelValue: {
      type: Array,
      default: () => []
    },
    tableData: {
      type: Object,
      default: () => {
        return {};
      }
    }
  },
  emits: {
    "update:model-value": null,
    "update:query-form": null,
    "update:del-rows": null,
    "update:del-row-ids": null,
    "update:selection-values": null,
    "on-get-table-data": null,
    "on-handle-selection-change": null,
    "on-handle-db-cell-click": null,
    "on-handle-cell-click": null,
    "on-handle-radio-change": null,
    "on-open-dynamic-table-select": null,
    "on-handle-confirm-selection": null,
    "on-handle-change-value": null,
    "on-del-dynamic-row": null,
    "on-add-dynamic-row": null
  },
  setup(props, { emit }) {
    const formItemTypes = [
      TableColumnOrFormTypeEnum.DYNAMICTABLESELECT,
      TableColumnOrFormTypeEnum.INPUT,
      TableColumnOrFormTypeEnum.INPUTNUMBER,
      TableColumnOrFormTypeEnum.SELECT,
      TableColumnOrFormTypeEnum.SELECTTREE,
      TableColumnOrFormTypeEnum.RATE,
      TableColumnOrFormTypeEnum.DATE,
      TableColumnOrFormTypeEnum.SWITCH,
      TableColumnOrFormTypeEnum.MONEYINPUT
    ];
    const $baseTableHeight = 1000; //inject("$baseTableHeight");
    const {
      isClickEdit = ref(false),
      isShowPagination = ref(true),
      total,
      isTree = ref(false),
      treeRowField = ref("id"),
      treeparentField = ref("parentid"),
      treeCheckStrictly = ref(false),
      isAddDynamicRow = ref(true), //是否增加自定义行
      isDelDynamicRow = ref(true), //是否删除自定义行
      isDragRow = ref(true),
      columnList,
      layout,
      maxHeight,
      pageSizes,
      isSelectRow,
      isHighLightRow,
      isShowEmptyText = ref(true),
      emptyText,
      menuConfig = ref({}),
      stripe,
      border,
      minWidth,
      showSummary,
      isLoading,
      dynamicConfig,
      templateOrignData,
      isMustHaveOneRow = ref(true),
      rowHeight,
      checkMethod,
      columnResizable
    } = toRefs(props.tableData);

    const _emitter = mitt();

    const $subFunc = () => {
      // eslint-disable-next-line prefer-rest-params
      Reflect.apply(_emitter.on, _emitter, _.toArray(arguments));
    };

    const $unsubFunc = () => {
      // eslint-disable-next-line prefer-rest-params
      Reflect.apply(_emitter.off, _emitter, _.toArray(arguments));
    };

    const route = useRoute();
    // const $sub = inject("$sub");
    // const $unsub = inject("$unsub");
    const expandRowKeys = ref([]);
    const defaultLayout = computed(() => {
      let initLayout = ["Total", "Sizes", "PrevJump", "PrevPage", "Number", "NextPage", "NextJump", "FullJump"];
      if (layout?.value) {
        initLayout = layout.value.split(",");
      }
      return initLayout;
    });

    const lineHeight = ref("small");
    const emitEditId = ref("");

    const tableV2Ref = ref(null);

    const tableQueryForm = ref({ ...props.queryForm });

    const elTableData = reactive(hODeepClone(props.tableData));

    const elDelRows = ref(props.delRows);
    const elDelRowIds = ref([...props.delRowIds]);
    const isExpandAllTree = ref(false); //展开树table
    const containerTableRef = ref();
    const optionLists = reactive({});
    const { toggle, isFullscreen } = useFullscreen(containerTableRef);

    const actualMaxHeight = (maxHeight && maxHeight.value) || backTableHeight();
    const height = ref(actualMaxHeight);

    /**
     * 页面路由名字
     */
    const pageName = computed(() => {
      return route.name;
    });
    const isDynamic = computed(() => {
      const { columnList } = elTableData;
      return columnList.some(item => {
        let isTure = item.type === TableColumnOrFormTypeEnum.DYNAMIC;
        if (isTure && item.isShowCallBack) {
          isTure = item.isShowCallBack();
        }
        return isTure;
      });
    });

    const isShowMenu = computed(() => {
      const { isShowFull, isShowSize } = menuConfig.value || {};
      return isShowFull || isShowSize;
    });

    const menuPosition = computed(() => {
      const { position } = menuConfig.value || {};
      return position || "right";
    });

    const editConfig = computed(() => {
      return {
        showIcon: false,
        enabled: isDynamic.value ? true : false,
        mode: "row",
        autoClear: false,
        showStatus: true
      };
    });

    /**
     * 获取树table第一层展开
     */
    const getExpandRowKeys = tableData => {
      if (!isTree.value || !tableData || expandRowKeys.value.length) return;
      // expandRowKeys.value.push(props.treeRootId);//只会在初始化时被触发一次
      // expandRowKeys.value.push("1");
      setTimeout(function () {
        const rootRow = tableV2Ref.value.getData(0);
        if (rootRow) {
          tableV2Ref.value.setTreeExpand([rootRow], true);
        }
      }, 2000); // 定时时间

      // tableData.forEach(item => {
      //   if (item.parentid === props.treeRootId) {
      //     //默认展开的行
      //     // expandRowKeys.value.push(item.id);
      //   }
      // });
    };

    //#region

    const getFooterCellClassName = ({ column }) => {
      if (!showSummary.value) return;
      const { columnList } = elTableData;
      const { field } = column;
      const columnItem = columnList.find(item => item.value === field);
      const { type } = columnItem;
      if (type === TableColumnOrFormTypeEnum.MONEYINPUT || type === TableColumnOrFormTypeEnum.MONEYTEXT) {
        return "money-cell";
      }
    };

    const clickFullScreen = () => {
      toggle().then(() => {
        handleHeight();
        tableRef.value.doLayout();
      });
    };
    const handleHeight = () => {
      if (isFullscreen.value) height.value = $baseTableHeight(1) + 200;
      else height.value = actualMaxHeight;
    };

    const getObjectKeyvalue = (row, key) => {
      const keys = key.split(".");
      const value = keys.reduce((pre, cur) => {
        return pre ? pre[cur] : undefined;
      }, row);

      return value;
    };

    const getTextKeyValue = (row, key) => {
      if (!key) return;
      let value = row[key];
      if (key.indexOf(".") >= 0) {
        value = getObjectKeyvalue(row, key);
      }
      return value;
    };

    const getEnumText = (row, dictCode, key) => {
      const enumList = getLocalStorage()[dictCode];
      let value = row[key];
      if (key.indexOf(".") >= 0) {
        value = getObjectKeyvalue(row, key);
      }
      if (key && enumList && enumList.length > 0) {
        const item = enumList.find(citem => citem.dictValue == value)?.dictLabel;
        return item || value;
      }
      return value;
    };

    const getMoneyValue = (row, key) => {
      let value = row[key];
      if (key.indexOf(".") >= 0) {
        value = getObjectKeyvalue(row, key);
      }
      if (value) {
        value = (value * 1).toFixed(2);
        value = formatMoneyThoud(value);
      }
      return value;
    };

    /**
     * 设置高亮行
     */
    const setCurrent = row => {
      tableV2Ref.value.setCurrentRow(row);
    };

    const sumNumber = (data, field) => {
      let count = 0;
      const { columnList } = elTableData;
      let columnItem = [];
      for (const item of data) {
        //判断若为金额，则用千分符展示
        columnItem = columnList.filter(item => item.value === field);
        let value = item[field];
        if (field.indexOf(".") >= 0) {
          value = getObjectKeyvalue(item, field);
        }
        const number = value ?? Number(value);
        const { isSummary = false } = columnItem[0] || {};
        if (isNaN(number) || !isSummary) {
          count = "-";
          break;
        } else {
          count += number;
        }
      }
      if (!isNaN(count)) {
        const type = columnItem.length && columnItem[0].type;
        const moneyTypes = [TableColumnOrFormTypeEnum.MONEYINPUT, TableColumnOrFormTypeEnum.MONEYTEXT];
        if (moneyTypes.includes(type)) {
          count = (count * 1).toFixed(2);
          count = formatMoneyThoud(count);
        }
      }

      return count;
    };
    /**
     * 统计所有列总和
     */
    const getSummery = ({ columns, data }) => {
      if (!elTableData.datalist.length) {
        return [];
      }
      const { setSummaryRow } = props.tableData;
      if (setSummaryRow) {
        const footer = setSummaryRow({ columns, data });
        return [footer];
      }
      const footer = columns.map((column, index) => {
        let result = "";
        if (index === 0) {
          result = "合计";
        } else if (column.field) {
          result = sumNumber(data, column.field);
        }
        return result;
      });
      return [footer];
    };

    /**
     * 值改变时合集发生变化
     */
    const updateFooterEvent = () => {
      const $table = tableV2Ref.value;
      $table.updateFooter();
    };

    /**
     * 获取下拉框树列表精工
     * @param {} code
     * @param {*} url
     * @param {*} key
     */
    const getOptionLists = (code, url, key) => {
      if (optionLists[key]) {
        return optionLists[key];
      }
      optionLists[key] = [];
      if (code) {
        optionLists[key] = getLocalStorage()[code];
        return optionLists[key];
      } else if (url) {
        queryList(url).then(res => {
          const { data } = res;
          optionLists[key] = data.rows;
          return optionLists[key];
        });
      }
    };

    /**
     * 处理table翻页以及换页面size
     * @param {} param0
     */
    const handlePageChange = ({ currentPage, pageSize }) => {
      tableQueryForm.value.pageNum = currentPage;
      tableQueryForm.value.pageSize = pageSize;
      emit("update:query-form", tableQueryForm.value);
      emit("on-get-table-data");
    };

    /**
     * 点击table排序
     * @param {} val
     */
    const handleSorted = async sortValue => {
      const { field, order } = sortValue.column;
      const val = {
        prop: field,
        order: order === "desc" ? "descending" : order
      };

      doSorted(val, tableQueryForm.value);
      emit("update:query-form", tableQueryForm.value);
      emit("on-get-table-data");
    };

    const handleSelectionChange = val => {
      const { records = [] } = val || {};
      emit("update:selection-values", records);
      emit("on-handle-selection-change", records);
    };

    const handleRadioChange = val => {
      const { newValue } = val || {};
      emit("update:selection-values", [newValue]);
      emit("on-handle-radio-change", newValue);
    };
    /**
     * 表单元素改变抛出
     * @param {} params
     */
    const onHandleChange = params => {
      showSummary && showSummary.value && updateFooterEvent();
      emit("on-handle-change-value", params);
    };

    /**
     * 双击单元格
     */
    const handleCellDBClick = params => {
      if (isTree.value) {
        //树结构table双击行展开table
        const { row } = params;
        const expandRecords = tableV2Ref.value.getTreeExpandRecords();
        const hasExpand = expandRecords.some(record => record.id == row.id);
        if (hasExpand) {
          tableV2Ref.value.setTreeExpand(row, false);
        } else {
          tableV2Ref.value.setTreeExpand(row, true);
        }
      }
      emit("on-handle-db-cell-click", params);
    };

    /**
     * 单击单元格
     */
    const handleCellClick = params => {
      emit("on-handle-cell-click", params);
    };

    const onOpenDynamicTableSelect = params => {
      emit("on-open-dynamic-table-select", params);
    };

    const onHandleConfirmSelection = params => {
      emit("on-handle-confirm-selection", params);
    };
    /**
     * 拖动表格表格
     */
    const setSort = () => {
      // 表格中需要实现行拖动，所以选中tr的父级元素

      const el = tableV2Ref.value.$el.querySelector(".body--wrapper>.vxe-table--body tbody"); // table

      Sortable.create(el, {
        ghostClass: "sortable-ghost",
        setData: function (dataTransfer) {
          dataTransfer.setData("Text", "");
        },
        onEnd: sortableEvent => {
          const newIndex = sortableEvent.newIndex;
          const oldIndex = sortableEvent.oldIndex;
          const currRow = elTableData.datalist.splice(oldIndex, 1)[0];
          elTableData.datalist.splice(newIndex, 0, currRow);
        }
      });
    };

    /**
     * 新增表格行
     * @param {*} row 当前点击行数据
     */
    const onAddRow = index => {
      if (!isAddDynamicRow.value) {
        emit("on-add-dynamic-row", { rowIndex: index });
        return;
      }
      const { datalist } = elTableData;
      const tempData = templateOrignData?.value || {};
      datalist.splice(index + 1, 0, hODeepClone(tempData));
      elTableData.datalist = [...datalist];

      // const index = datalist.findIndex((item) => item.id === row.id)
      // if (~index) {
      //   // elTableData.datalist.push(elTableData.datalist[0])
      //   datalist.splice(index + 1, 0, {})
      //   elTableData.datalist = [...datalist]
      //
      // }
    };

    /**
     * 删除行
     * @param {*} row 当前点击行数据
     */
    const onDelRow = (row, index) => {
      if (!isDelDynamicRow.value) {
        emit("on-del-dynamic-row", { row, rowIndex: index });
        return;
      }
      confirm("你确定要删除选中项吗", async () => {
        const { datalist } = elTableData;

        const delRow = datalist.splice(index, 1);
        elTableData.datalist = [...datalist];

        if (delRow.length && delRow[0] && delRow[0].id) {
          elDelRows.value.push(delRow[0]);
          elDelRowIds.value = elDelRows.value.map(item => item.id);
          emit("update:del-rows", elDelRows.value);
          emit("update:del-row-ids", elDelRowIds.value);
        }
      });
    };

    const dynamicCellClassName = rowParams => {
      const { fixed } = rowParams;

      return isDynamic.value && isDragRow.value && !fixed ? "drag" : "";
    };

    const getEventName = () => {
      return pageName.value + emitEditId.value;
    };

    /**
     * 还原行数据
     */
    const revertRowData = () => {
      const $table = tableV2Ref.value;
      $table.clearEdit().then(() => {
        // 还原行数据
        $table.revertData();
      });
    };

    /**
     * 展开/折叠树
     */
    const handleExpandTree = () => {
      isExpandAllTree.value = !isExpandAllTree.value;
      tableV2Ref.value.setAllTreeExpand(isExpandAllTree.value);
    };

    //#endregion
    onMounted(() => {
      isDynamic.value && isDragRow.value && setSort();
      if (!isClickEdit.value) return;
      emitEditId.value = uuid();
      const eventName = getEventName();
      const cancelEventName = `${getEventName()}cancel`;

      $subFunc(eventName, ({ row }) => {
        const $table = tableV2Ref.value;
        $table.setEditRow(row);
      });
      $subFunc(cancelEventName, ({ row }) => {
        revertRowData(row);
      });
    });

    onUnmounted(() => {
      const eventName = getEventName();
      const cancelEventName = `${getEventName()}cancel`;

      $unsubFunc(eventName);
      $unsubFunc(cancelEventName);
    });
    //#region

    // watch(
    //   () => props.modelValue,
    //   (newVal) => {
    //     elTableData.datalist = newVal
    //   },
    //   {
    //     deep: true,
    //     immediate: true,
    //   }
    // )
    watch(
      () => props.queryForm,
      () => {
        tableQueryForm.value = { ...props.queryForm };
      },
      {
        deep: true
      }
    );
    watch(
      () => props.modelValue,
      newVal => {
        getExpandRowKeys(newVal);
        if (JSON.stringify(newVal) === JSON.stringify(elTableData.datalist)) return;
        elTableData.datalist = hODeepClone(newVal);
        if (newVal && newVal.length > 0) {
          if (tableV2Ref.value) {
            if (isSelectRow) {
              setCurrent(elTableData.datalist[0]);
            }
            // showSummary && showSummary.value && updateFooterEvent()
          }
        }
      },
      { deep: true, immediate: true }
    );

    watch(
      () => elTableData.datalist,
      newVal => {
        if (JSON.stringify(newVal) === JSON.stringify(props.modelValue)) return;
        emit("update:model-value", hODeepClone(elTableData.datalist));

        if (tableV2Ref.value) {
          // showSummary && showSummary.value && updateFooterEvent()
        }
      },
      { deep: true, immediate: true }
    );

    return {
      TableColumnOrFormTypeEnum,
      containerTableRef,
      tableV2Ref,
      formItemTypes,
      isShowMenu,
      menuConfig,
      isFullscreen,
      lineHeight,
      isLoading,
      border,
      elTableData,
      editConfig,
      height,
      showSummary,
      stripe,
      columnList,
      isShowPagination,
      isShowEmptyText,
      tableQueryForm,
      defaultLayout,
      dynamicConfig,
      total,
      isDynamic,
      menuPosition,
      minWidth,
      emptyText,
      isMustHaveOneRow,
      rowHeight,
      checkMethod,
      isClickEdit,
      emitEditId,
      expandRowKeys,
      treeCheckStrictly,
      isTree,
      treeRowField,
      treeparentField,
      isExpandAllTree,
      isSelectRow,
      isHighLightRow,
      columnResizable,
      pageSizes,
      handleExpandTree,
      getMoneyValue,
      getOptionLists,
      getObjectKeyvalue,
      dynamicCellClassName,
      clickFullScreen,
      getSummery,
      getDataEmptyImg,
      handleCellClick,
      handleCellDBClick,
      handleSelectionChange,
      handleRadioChange,
      handleSorted,
      handlePageChange,
      onAddRow,
      onDelRow,
      onHandleConfirmSelection,
      onOpenDynamicTableSelect,
      onHandleChange,
      getTextKeyValue,
      getEnumText,
      getFooterCellClassName,
      Delete,
      Plus
    };
    //#endregion
  }
});
</script>

<style lang="scss" scoped>
.common-table-wrap {
  display: flex;
  flex: 1;
  flex-direction: column;
  .menu {
    text-align: v-bind("menuPosition");
  }
  .common-vxe-table {
    flex: 1;
  }
  .empty-btn {
    padding: 25px 0 15px;
  }
  .pager {
    padding: 15px;
  }
  .vab-data-empty {
    max-width: 200px;
  }
  :deep() {
    .drag {
      cursor: move;
    }
    .el-form-item {
      margin-bottom: 0;
    }
    .el-input-number {
      width: 100%;
      .el-input__inner {
        text-align: left;
      }
    }
    .money-cell {
      text-align: right;
    }
    .is--disabled {
      .vxe-radio--icon,
      .vxe-checkbox--icon {
        color: #f2f2f2;
      }
    }
  }
}
</style>
